package com.lzy.utils;

import java.io.*;
import java.util.zip.*;

import org.apache.tools.bzip2.CBZip2InputStream;
import org.apache.tools.bzip2.CBZip2OutputStream;

import com.jcraft.jzlib.JZlib;
import com.jcraft.jzlib.ZInputStream;
import com.jcraft.jzlib.ZOutputStream;

/**
 * @author lyw
 * @Date 2023/2/21-下午11:01
 */
public class GZipUtil {

  public static byte[] convertByteArr(Object obj) throws IOException {

    byte[] result = null;

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(baos);
    os.writeObject(obj);
    result = baos.toByteArray();
    os.flush();
    os.close();
    baos.flush();
    baos.close();

    return result;
  }

  public static Object convertObject(byte[] arr) throws IOException, ClassNotFoundException {
    ByteArrayInputStream bais = new ByteArrayInputStream(arr);
    ObjectInputStream is = new ObjectInputStream(bais);
    Object object = is.readObject();
    is.close();
    bais.close();
    return object;
  }

  /***
   * 压缩GZip
   *
   * @param data
   * @return
   */
  public static byte[] gZip(byte[] data) {
    byte[] b = null;
    try {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      GZIPOutputStream gzip = new GZIPOutputStream(bos);
      gzip.write(data);
      gzip.finish();
      gzip.close();
      b = bos.toByteArray();
      bos.close();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return b;
  }

  /***
   * 解压GZip
   *
   * @param data
   * @return
   */
  public static byte[] unGZip(byte[] data) {
    byte[] b = null;
    try {
      ByteArrayInputStream bis = new ByteArrayInputStream(data);
      GZIPInputStream gzip = new GZIPInputStream(bis);
      byte[] buf = new byte[1024];
      int num = -1;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      while ((num = gzip.read(buf, 0, buf.length)) != -1) {
        baos.write(buf, 0, num);
      }
      b = baos.toByteArray();
      baos.flush();
      baos.close();
      gzip.close();
      bis.close();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return b;
  }


  /***
   * 压缩Zip
   *
   * @param data
   * @return
   */
  public static byte[] zip(byte[] data) {
    byte[] b = null;
    try {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ZipOutputStream zip = new ZipOutputStream(bos);
      ZipEntry entry = new ZipEntry("zip");
      entry.setSize(data.length);
      zip.putNextEntry(entry);
      zip.write(data);
      zip.closeEntry();
      zip.close();
      b = bos.toByteArray();
      bos.close();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return b;
  }

  /***
   * 解压Zip
   *
   * @param data
   * @return
   */
  public static byte[] unZip(byte[] data) {
    byte[] b = null;
    try {
      ByteArrayInputStream bis = new ByteArrayInputStream(data);
      ZipInputStream zip = new ZipInputStream(bis);
      while (zip.getNextEntry() != null) {
        byte[] buf = new byte[1024];
        int num = -1;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ((num = zip.read(buf, 0, buf.length)) != -1) {
          baos.write(buf, 0, num);
        }
        b = baos.toByteArray();
        baos.flush();
        baos.close();
      }
      zip.close();
      bis.close();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return b;
  }


  /***
   * 压缩BZip2
   *
   * @param data
   * @return
   */
  public static byte[] bZip2(byte[] data) {
    byte[] b = null;
    try {
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      CBZip2OutputStream bzip2 = new CBZip2OutputStream(bos);
      bzip2.write(data);
      bzip2.flush();
      bzip2.close();
      b = bos.toByteArray();
      bos.close();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return b;
  }

  /***
   * 解压BZip2
   *
   * @param data
   * @return
   */
  public static byte[] unBZip2(byte[] data) {
    byte[] b = null;
    try {
      ByteArrayInputStream bis = new ByteArrayInputStream(data);
      CBZip2InputStream bzip2 = new CBZip2InputStream(bis);
      byte[] buf = new byte[1024];
      int num = -1;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      while ((num = bzip2.read(buf, 0, buf.length)) != -1) {
        baos.write(buf, 0, num);
      }
      b = baos.toByteArray();
      baos.flush();
      baos.close();
      bzip2.close();
      bis.close();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
    return b;
  }


  /**
   * 把字节数组转换成16进制字符串
   *
   * @param bArray
   * @return
   */
  public static String bytesToHexString(byte[] bArray) {
    StringBuffer sb = new StringBuffer(bArray.length);
    String sTemp;
    for (int i = 0; i < bArray.length; i++) {
      sTemp = Integer.toHexString(0xFF & bArray[i]);
      if (sTemp.length() < 2)
        sb.append(0);
      sb.append(sTemp.toUpperCase());
    }
    return sb.toString();
  }

  /**
   *jzlib 压缩数据
   *
   * @param object
   * @return
   * @throws IOException
   */
  public static byte[] jzlib(byte[] object) {

    byte[] data = null;
    try {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      ZOutputStream zOut = new ZOutputStream(out,
              JZlib.Z_DEFAULT_COMPRESSION);
      DataOutputStream objOut = new DataOutputStream(zOut);
      objOut.write(object);
      objOut.flush();
      zOut.close();
      data = out.toByteArray();
      out.close();

    } catch (IOException e) {
      e.printStackTrace();
    }
    return data;
  }

  /**
   *jzLib压缩的数据
   *
   * @param object
   * @return
   * @throws IOException
   */
  public static byte[] unjzlib(byte[] object) {

    byte[] data = null;
    try {
      ByteArrayInputStream in = new ByteArrayInputStream(object);
      ZInputStream zIn = new ZInputStream(in);
      byte[] buf = new byte[1024];
      int num = -1;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      while ((num = zIn.read(buf, 0, buf.length)) != -1) {
        baos.write(buf, 0, num);
      }
      data = baos.toByteArray();
      baos.flush();
      baos.close();
      zIn.close();
      in.close();

    } catch (IOException e) {
      e.printStackTrace();
    }
    return data;
  }
}
